package com.zz.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zz.domain.StudentMachine;
import com.zz.mapper.StudentMachineMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class StudentMachineService {
    @Autowired
    private StudentMachineMapper studentMachineMapper;

    // 心跳超时时间(5分钟)
    private static final long HEARTBEAT_TIMEOUT =1000;

    public void registerMachine(StudentMachine machine) {
        // 根据IP地址检查是否已注册（而非machineId）
        LambdaQueryWrapper<StudentMachine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentMachine::getIpAddress, machine.getIpAddress());
        StudentMachine existing = studentMachineMapper.selectOne(queryWrapper);

        if (existing != null) {
            // 存在则更新：保留原记录ID，仅更新必要字段
            machine.setMachineId(existing.getMachineId()); // 关键！设置已存在记录的ID
            studentMachineMapper.updateById(machine); // 使用updateById确保精准更新
        } else {
            studentMachineMapper.insert(machine); // 新增
        }
    }


    public List<StudentMachine> getAllMachines() {
        return studentMachineMapper.selectAllMachines();
    }

    public void in(Date da, String machineId) {
        System.out.println("进入in方法，machineId=" + machineId);

        if (machineId == null || machineId.isEmpty()) {
            System.out.println("警告：machineId为空！");
            return;
        }

        // 先检查是否有超时的机器并更新为离线
        checkAndUpdateTimeoutMachines();

        // 更新当前机器的心跳和状态
        StudentMachine updateMachine = new StudentMachine();
        updateMachine.setLastHeartbeat(da);
        updateMachine.setStatus("online");

        LambdaUpdateWrapper<StudentMachine> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(StudentMachine::getMachineId, machineId);

        int affectedRows = studentMachineMapper.update(updateMachine, wrapper);
        System.out.println("更新影响行数: " + affectedRows);

        if (affectedRows == 0) {
            System.out.println("警告：未找到machineId=" + machineId + "的记录");
        }
    }

    // 新增方法：检查并更新超时机器状态
    @Scheduled(fixedRate = 1000)
    private void checkAndUpdateTimeoutMachines() {
        Date timeoutThreshold = new Date(System.currentTimeMillis() - HEARTBEAT_TIMEOUT);

        // 找出所有在线但心跳超时的机器
        LambdaQueryWrapper<StudentMachine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentMachine::getStatus, "online")
                .lt(StudentMachine::getLastHeartbeat, timeoutThreshold);

        List<StudentMachine> timeoutMachines = studentMachineMapper.selectList(queryWrapper);

        if (!timeoutMachines.isEmpty()) {
            // 批量更新这些机器状态为离线
            StudentMachine updateEntity = new StudentMachine();
            updateEntity.setStatus("offline");

            LambdaUpdateWrapper<StudentMachine> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.in(StudentMachine::getMachineId,
                    timeoutMachines.stream().map(StudentMachine::getMachineId).collect(Collectors.toList()));

            int updatedCount = studentMachineMapper.update(updateEntity, updateWrapper);
            System.out.println("已将 " + updatedCount + " 台超时机器状态更新为离线");
        }
    }

    public List<StudentMachine> ge() {
        return studentMachineMapper.selectList(
                new LambdaQueryWrapper<StudentMachine>()
                        .select(StudentMachine::getMachineId,
                                StudentMachine::getLastHeartbeat)
        );
    }

    public Integer getConnectedStudentCount() {
        LambdaQueryWrapper<StudentMachine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentMachine::getIsActive, true)
                .eq(StudentMachine::getStatus, "online")
                .ge(StudentMachine::getLastHeartbeat,
                        new Date(System.currentTimeMillis() - HEARTBEAT_TIMEOUT));
        Long count = studentMachineMapper.selectCount(wrapper);
        return Math.toIntExact(count); // 安全转换Long到int
        
    }

    public Integer getSubmittedStudentCount() {
        LambdaQueryWrapper<StudentMachine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentMachine::getIsActive, true)
                .eq(StudentMachine::getStatus, "submitted");

        return Math.toIntExact(studentMachineMapper.selectCount(wrapper));
    }


    public void updateStudentStatus(String machineId, String status) {
        StudentMachine updateMachine = new StudentMachine();
        updateMachine.setStatus(status);

        LambdaUpdateWrapper<StudentMachine> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(StudentMachine::getMachineId, machineId);

        studentMachineMapper.update(updateMachine, wrapper);
    }

    public StudentMachine getMachineByExamNumber(String examNumber) {
        LambdaQueryWrapper<StudentMachine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StudentMachine::getExamnumber, examNumber);
        return studentMachineMapper.selectOne(wrapper);
    }
}